package com.xiao.tripmateai.app;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import com.xiao.tripmateai.advisor.MyLoggerAdvisor;
import com.xiao.tripmateai.service.TimeService;
import com.xiao.tripmateai.tools.FileOperationTool;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.io.IOException;

import org.springframework.core.io.ResourceLoader;


@Component
@Slf4j
public class AiService {

    private final ChatClient chatClient;
    private final String systemPrompt; // 改为从文件加载

    @Autowired
    private ResourceLoader resourceLoader;



    private static final String SYSTEM_PROMPT = "你是一个旅行规划专家";
    @Resource
    private VectorStore tripAppVectorStore;


    /**
     * 初始化 chatClient
     * @param dashscopeChatModel
     */
    public AiService(ChatModel dashscopeChatModel, JdbcChatMemoryRepository jdbcChatMemoryRepository) throws IOException {
        System.out.println("AiService 执行了");
        // 初始化基于文件的 对话记忆化
        String fileDir = System.getProperty("user.dir") + "/temp/chat-memory";
        // 从文件加载系统提示词
        this.systemPrompt = loadPromptFromFile("classpath:prompts/travel_agent_prompt.md");
        //使用spring ai 自带的对话记忆化 内存
//        // 初始化基于内存的对话记忆
//        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
//                .chatMemoryRepository(new InMemoryChatMemoryRepository())
//                .maxMessages(20)
//                .build();

        //基于jdbc 的 对话持久化 mysql
        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
                .chatMemoryRepository(jdbcChatMemoryRepository)
                .maxMessages(20)
                .build();

        chatClient = ChatClient.builder(dashscopeChatModel)
                //.defaultTools(tools)
                //.defaultSystem(this.systemPrompt)
                .defaultSystem(this.systemPrompt)
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
                .build();


    }

    /**
     * AI 基础对话（支持多轮对话记忆）
     *
     * @param message
     * @param chatId
     * @return
     */
    @Resource
    private ToolCallbackProvider combinedToolCallbackProvider;

    public String doChat(String message, String chatId) {

        ChatResponse chatResponse = chatClient
                .prompt()
                //.tools(new TimeService())
                .tools(new FileOperationTool(),new TimeService())
                .toolCallbacks(combinedToolCallbackProvider)
                .user(message)
                .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
                .advisors(new MyLoggerAdvisor())
                .call()
                .chatResponse();

        String content = chatResponse.getResult().getOutput().getText();
        //log.info("content: {}", content);
        return content;
    }
    // 使用 Hutool 加载提示词
    private String loadPromptFromFile(String filePath) {
        try {
            if (filePath.startsWith("classpath:")) {
                // 处理类路径资源
                String classpath = filePath.substring(10);
                ClassPathResource resource = new ClassPathResource(classpath);
                return resource.readUtf8Str();
            } else {
                // 处理文件系统路径
                return FileUtil.readUtf8String(filePath);
            }
        } catch (Exception e) {
            throw new RuntimeException("加载提示词失败: " + filePath, e);
        }
    }

    /**
     * AI 基础对话（支持多轮对话记忆，SSE 流式传输）
     * 目前使用的方法
     * @param message
     * @param chatId
     * @return
     */
    public Flux<String> doChatByStream(String message, String chatId) {
        return chatClient
                .prompt()
                .toolCallbacks(combinedToolCallbackProvider)
                .user(message)
//                //应用日志
//                .advisors(new MyLoggerAdvisor())
                //记忆持久化
                .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
                //应用知识库问答
                //.advisors(new QuestionAnswerAdvisor(tripAppVectorStore))
                .stream()
                .content();
    }

    // AI 调用 MCP 服务

//    @Resource
//    private ToolCallbackProvider toolCallbackProvider;

    /**
     * AI 恋爱报告功能（调用 MCP 服务）
     *
     * @param message
     * @param chatId
     * @return
     */
    public String doChatWithMcp(String message, String chatId) {
        ChatResponse chatResponse = chatClient
                .prompt()
                .user(message)
                .advisors(spec -> spec.param(ChatMemory.CONVERSATION_ID, chatId))
                // 开启日志，便于观察效果
                .advisors(new MyLoggerAdvisor())
                .toolCallbacks(combinedToolCallbackProvider)
                .call()
                .chatResponse();
        String content = chatResponse.getResult().getOutput().getText();
        log.info("content: {}", content);
        return content;
    }
}